#include"BlockRender.h"
#include"ChunkRender.h"

namespace Craft
{
	TexBlockRender::TexBlockRender()
	{
	}

	TexBlockRender::~TexBlockRender()
	{
	}

	TexBlockRender::TexBlockRender(TexInfo tex[])
	{
		for (size_t i = 0; i < 6; i++)
		{
			texcrood[i] = tex[i];
		}
	}

	void TexBlockRender::render(ChunkRender*rd, const glm::vec3& pos)
	{
		if (rd != nullptr)
		{
			rd->add_Block(texcrood, pos);
		}
	}


	/*
		@brief plant block
	*/
	TexPlantRender::TexPlantRender()
	{
	}
	
	TexPlantRender::TexPlantRender(TexInfo tex) :texcrood(tex)
	{
	}

	TexPlantRender::~TexPlantRender()
	{

	}

	void TexPlantRender::render(ChunkRender*rd, const glm::vec3& pos)
	{
		if (rd != nullptr)
		{
			rd->add_Plant(texcrood, pos);
		}
	}


	VertexArrays  DepdentBlockRender::va(1000, VertexFormat(3, 3, 0, 2));
	ElementsBuffe DepdentBlockRender::eb(1000);

	void DepdentBlockRender::generate_Block(Block block)
	{
		va.clear();
		eb.clear();
		
		unsigned int i = va.get_vertex_count();
		glm::vec3 pos = block.get_pos();

		currblock = block;
		if (!currblock.get_Id())
			return;

		// 1 r
		va.addPrimitive(4,
		{
			pos.x + 0.5f, pos.y + 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
			pos.x + 0.5f, pos.y - 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
			pos.x + 0.5f, pos.y - 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
			pos.x + 0.5f, pos.y + 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
		});

		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});


		// 2 l
		va.addPrimitive(4,
		{
			pos.x - 0.5f, pos.y + 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
			pos.x - 0.5f, pos.y - 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
			pos.x - 0.5f, pos.y - 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
			pos.x - 0.5f, pos.y + 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
		});

		i += 4;
		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});

		// 3 t
		va.addPrimitive(4,
		{
			pos.x - 0.5f, pos.y + 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
			pos.x - 0.5f, pos.y + 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
			pos.x + 0.5f, pos.y + 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
			pos.x + 0.5f, pos.y + 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
		});

		i += 4;
		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});

		// 4 b
		va.addPrimitive(4,
		{
			pos.x - 0.5f, pos.y - 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
			pos.x - 0.5f, pos.y - 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
			pos.x + 0.5f, pos.y - 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
			pos.x + 0.5f, pos.y - 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
		});

		i += 4;
		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});

		// 5 f
		va.addPrimitive(4,
		{
			pos.x - 0.5f, pos.y + 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
			pos.x - 0.5f, pos.y - 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
			pos.x + 0.5f, pos.y - 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
			pos.x + 0.5f, pos.y + 0.5f, pos.z + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
		});

		i += 4;
		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});

		// 6
		va.addPrimitive(4,
		{
			pos.x + 0.5f, pos.y + 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
			pos.x + 0.5f, pos.y - 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
			pos.x - 0.5f, pos.y - 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
			pos.x - 0.5f, pos.y + 0.5f, pos.z - 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
		});

		i += 4;
		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});

		m_buffer.updateVA(va);
		m_buffer.updateEB(eb);
	}

	std::vector<std::shared_ptr<BlockRender> > BlockRenderManger::renders;

	void BlockRenderManger::init()
	{
		renders.push_back(std::make_shared<TexBlockRender>());
		renders.push_back(std::make_shared<TexBlockRender>());
	}

	void BlockRenderManger::clear()
	{
		renders.clear();
	}

	void BlockRenderManger::render(int id, glm::vec3 pos, ChunkRender*rd)
	{
		if (renders[id])
			renders[id]->render(rd, pos);
	}

	void BlockRenderManger::push_render(std::shared_ptr<BlockRender> rend)
	{
		renders.push_back(rend);
	}


}